﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ODS.Config;
using ODS.Utils;
using System.IO;
using ODS.Model;
using System.Xml.Linq;
using System.Windows;

namespace ODS.WebService.DeviceData
{
    public class FindDeviceEventsSevice
    {
        static bool IsAuthenticated = true;

        public static async Task<InfoResult> FindDeviceEvent(String imei, DateTime minDate, DateTime maxDate, int page, int offset)
        {
            String minDateFormat = minDate.ToString("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
            String maxDateFormat = maxDate.ToString("yyyy-MM-dd'T'HH:mm:ss.SSSZ");

            String url = Constants.SERVER_URL + "/devices/" + imei + "/events/find";
            String body = String.Format("<eventFilter><minRegisteredAt>{0}</minRegisteredAt><maxRegisteredAt>{1}</maxRegisteredAt><page><size>{2}</size><offset>{3}</offset></page></eventFilter>",
                                            minDateFormat,
                                            maxDateFormat,
                                            page,
                                            offset);

            InfoResult result;
            try
            {
                Stream xmlStream = await RESTfulService.HTTPPostRequest(url, body);
                List<EventDetailModel> obj = ParseXML(xmlStream);

                #region check authenticate
                if (!IsAuthenticated)
                {
                    InfoResult result_login = await Login_Logout.LoginService.loginService(App.userLogin.UserLoginName, App.userLogin.UserPassword);
                    if (result_login.IsSuccess)
                    {
                        if ((String)result_login.ReturnedObject == Constants.SUCCESS)
                        {
                            IsAuthenticated = true;

                            return await FindDeviceEvent(imei, minDate, maxDate, page, offset);
                        }
                        else
                        {
                            MessageBox.Show((String)result_login.ReturnedObject);
                            App.BackToLoginPage();

                        }
                    }
                    else
                    {
                        MessageBox.Show(result_login.Error);
                        App.BackToLoginPage();

                    }


                }
                #endregion

                result = new InfoResult(null, obj);
            }
            catch (Exception ex)
            {
                result = new InfoResult(ex.Message, null);
            }

            return result;
        }

        private static List<EventDetailModel> ParseXML(Stream xmlStream)
        {
            List<EventDetailModel> listEventModel = new List<EventDetailModel>();
            XDocument doc = XDocument.Load(xmlStream);

            var Authenticate = (from authen in doc.Descendants("unauthorized")
                                select new
                                {

                                }).FirstOrDefault();
            if (Authenticate != null)
            {
                IsAuthenticated = false;
                return null;
            }

            var Events = from Event in doc.Descendants("eventDetails")
                         select new
                         {
                             EventId = Event.Element("eventId").Value,
                             RegisteredAt = Event.Element("registeredAt").Value,                            
                             EventType = Event.Element("eventType").Value,

                             CommandType = (from commandType in Event.Descendants("commandType")
                                            select new
                                            {
                                                
                                                Value = Event.Element("commandType").Value,
                                            }).FirstOrDefault(),
                             ReadAt = (from readAt in Event.Descendants("readAt")
                                           select new
                                           {
                                               Value = Event.Element("readAt").Value,
                                           }).FirstOrDefault(),
                             MonitorType = (from monitorType in Event.Descendants("monitorType")
                                           select new
                                           {
                                               Value = Event.Element("monitorType").Value,
                                           }).FirstOrDefault(),

                             Messages = from Message in Event.Descendants("message")
                                        select new
                                        {
                                            GeneratedAt = Message.Element("generatedAt").Value,
                                            Heading = Message.Element("heading").Value,
                                            Ignition = Message.Element("ignition").Value,
                                            Latitude = Message.Element("latitude").Value,
                                            Longitude = Message.Element("longitude").Value,
                                            Odometer = Message.Element("odometer").Value,
                                            ReceivedAt = Message.Element("receivedAt").Value,
                                            Speed = Message.Element("speed").Value,
                                        }


                         };
            foreach (var Event in Events)
            {
                EventDetailModel EventModel = new EventDetailModel();
                EventModel.EventId = Event.EventId;
                EventModel.RegisteredAt = CommonUtil.ParseDateTimeFromString( Event.RegisteredAt);
                EventModel.EventType = Event.EventType;

                if (Event.CommandType != null)
                    EventModel.CommandType = Event.CommandType.Value;
                if (Event.ReadAt != null)
                    EventModel.ReadAt = CommonUtil.ParseDateTimeFromString(Event.ReadAt.Value);
                if (Event.MonitorType != null)
                    EventModel.MonitorType = Event.MonitorType.Value;
                

                if (Event.Messages != null && Event.Messages.Count() > 0)
                {
                    EventModel.MessageModel = new MessageModel();
                    EventModel.MessageModel.GeneratedAt = CommonUtil.ParseDateTimeFromString(Event.Messages.First().GeneratedAt);
                    EventModel.MessageModel.Heading = Event.Messages.First().Heading;
                    EventModel.MessageModel.Ignition = Event.Messages.First().Ignition;
                    EventModel.MessageModel.Latitude = Event.Messages.First().Latitude;
                    EventModel.MessageModel.Longitude = Event.Messages.First().Longitude;
                    EventModel.MessageModel.Odometer = Event.Messages.First().Odometer;
                    EventModel.MessageModel.ReceivedAt = CommonUtil.ParseDateTimeFromString(Event.Messages.First().ReceivedAt);
                    EventModel.MessageModel.Speed = Event.Messages.First().Speed;
                }

                listEventModel.Add(EventModel);
            }


            return listEventModel;

        }
    }
}
